# -*- coding: utf-8 -*-
"""
 核心框架
 Created by Quant on 2018-03-08
"""
__author__ = 'Quant'

from functools import wraps
from flask import request, current_app
from app.core import util, auth
from app.core.redis import redis
from app.core.const import Const


def auth_filter():
    """
    认证过滤器，每次请求都会首先经过这里
    :return:
    """
    url = request.path

    # 获取配置的忽略地址
    auth_ignore_url = current_app.config['AUTH_IGNORE_URL']
    # 循环判断是否忽略的地址
    is_ignore = False
    for ignore_url in auth_ignore_url:
        if (url.startswith(ignore_url)):
            is_ignore = True
            break
    # 如果是忽略地址，那么就直接跳过
    if is_ignore:
        return

    # 获取headers中的认证头信息
    auth_header = request.headers.get(Const.AUTH_HEADER)

    if (not auth_header):
        util.make_abort_500('没有提供正确的认证头信息')

    # 根据空格拆分
    auth_tokenArr = auth_header.split(" ")
    # 验证头信息
    if (not auth_tokenArr or auth_tokenArr[0] != Const.AUTH_HEADER_PREFIX or len(auth_tokenArr) != 2):
        util.make_abort_500('请传递正确的验证头信息')
    else:

        # 取拆分后第二个参数，即token值
        auth_token = auth_tokenArr[1]
        # 先从redis中判断token是否过期
        flag = redis.exists(Const.AUTH_TOKEN.format(auth_token))
        # 验证不成功，那么直接抛出异常
        if (not flag):
            util.make_abort_500('token已经过期')

        # 验证token有效性
        result = auth.check_auth_token(auth_token)
        if (not bool(result['success'])):
            util.make_abort_500(result['msg'])

        # 重新设置token的时间
        redis.expire(Const.AUTH_TOKEN.format(auth_token), Const.AUTH_TOKEN_EXPIRES)


# 权限拦截装饰器
def permissions(perms=[]):
    """
    权限拦截装饰器
    :param perms:
    :return:
    """

    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kw):
            # 此处做权限的拦截操作
            return func(*args, **kw)

        return wrapper

    return decorator


# 角色拦截装饰器
def roles():
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kw):
            # 此处做权限的拦截操作
            if (args[0] == 1):
                return func(*args, **kw)
            else:
                util.make_abort("无权限访问")

        return wrapper

    return decorator
